<template>
  <el-card style="margin-left: 10px;margin-right: 10px;">
    <div>
      <div>
        <h1>节点二</h1>
        <h2>电池电量</h2>
        <div style="display: block;margin-left: 30%;margin-top: -50px;">
          <h3>当前电池电量：</h3>
          <span>{{ ele }}</span>
          <!-- <span v-show="!clickValue4">暂无数据</span>           -->
        </div>
        <div style="display: block;margin-left: 50%;margin-top: -50px;">
          <h3>未来预测值：</h3>
          <div v-show="preIf">
            <span>{{ preValue3[9] }}%</span>
          </div>
          <div v-show="!preIf">
            <span>请开始预测</span>
          </div>

          <!-- <span v-show="!clickValue4">暂无数据</span>           -->
        </div>
        <!-- 按钮 -->
        <div>
          <el-button @click="clickOne" style="float: right;margin-top: -50px;margin-right: 200px;">开始画图</el-button>
          <el-button @click="stopClickOne" style="float: right;margin-top: -50px;margin-right: 100px;">停止画图</el-button>
          <el-button @click="pre3" style="float: right;margin-top: -50px;">开始预测</el-button>
        </div>
      </div>
    </div>
  </el-card>
  <el-card style="margin-top:10px;margin-left: 10px;margin-right: 10px;">
    <div>
      <!-- 历史数据图 -->
      <div>
        <h1>数据展示</h1>
        <div id="chart11" ref="chart11"
          style="display: inline-block;margin-left:0px ;margin-bottom: 20px;width: 45%;margin-top:30px;height: 300px;">
        </div>
        <div id="chart12" ref="chart12"
          style="display: inline-block;margin-left:10px ;margin-bottom: 20px;width: 45%;margin-top:30px;height: 300px;">
        </div>
      </div>
      <!-- 异常数据表格 -->
      <div style="width:100%">
        <div>
          <h2 style="display: inline;">异常数据处理</h2>
          <el-button text style="display: inline;float: right;"
            @click="exportExcel('eleErrorTable', '节点一电量异常记录.xlsx')">异常数据导出</el-button>
        </div>
        <el-table id="eleErrorTable" :data="tableData4"
          style="width: 100%;max-height: 200px; height: 100%; overflow: auto;">
          <el-table-column prop="value" label="异常温度值"></el-table-column>
          <el-table-column prop="time" label="时间"></el-table-column>
        </el-table>
      </div>
    </div>
  </el-card>
</template>


<script>
import axios from 'axios';
import * as echarts from 'echarts';
import * as XLSX from 'xlsx';
import FileSaver from 'file-saver';


let arr4 = [95, 95, 95, 95, 95, 95, 95, 95, 95, 95];


export default {
  data() {
    return {
      name: 'index14',
      arrFour: [95, 95, 95, 95, 95, 95, 95, 95, 95, 95],
      eleData: '暂无数据',
      clickValue4: false,
      preIf: false,
      ele: '暂无数据',
      preValue1: 0,
      preValue2: 0,
      preValue3: 0,
      tableData4: [],
      gaugeData: [
        {
          value: 90,
          name: '电池电量',
          title: {
            offsetCenter: ['0%', '30%']
          },
          detail: {
            valueAnimation: true,
            offsetCenter: ['0%', '-20%']
          }
        }
      ],
      eleWarning: false,
      realData: 35,
    };
  },
  methods: {
    updateChartData(id) {
        const chart = echarts.getInstanceByDom(document.getElementById(id));
        // 更新数据项的值
        chart.setOption({
          series: [
          {
            type: 'gauge',
            startAngle: 90,
            endAngle: -270,
            pointer: {
              show: false
            },

            tooltip: {},
            progress: {
              show: true,
              overlap: false,
              roundCap: true,
              clip: false,
              itemStyle: {
                borderWidth: 1,
                borderColor: '#464646'
              }
            },
            axisLine: {
              lineStyle: {
                width: 10
              }
            },
            splitLine: {
              show: false,
              distance: 20,
              length: 10
            },
            axisTick: {
              show: false
            },
            axisLabel: {
              show: false,
              distance: 50
            },
            data: this.realData,
            title: {
              fontSize: 30
            },
            detail: {
              width: 120,
              height: 40,
              fontSize: 35,
              color: 'inherit',
              borderColor: 'inherit',
              borderRadius: 30,
              borderWidth: 1,
              formatter: '{value}%'
            }
          }
        ]
          // [
          //   {
          //     data: [{ value: this.realData }]
          //   },
          //   {
          //     data: [{ value: this.realData }]
          //   }
          // ]
        });
    },
    sendMessage() {
      axios.post("http://127.0.0.1:8000/update", { name: "张无忌", age: 24 },).then((res) => {
        console.log(res.data);
      });
    },
    drawLine(id, title, realdata) {
      var chart = echarts.getInstanceByDom(document.getElementById(id));
      if (chart) {
        chart.dispose(); // 如果图表已经存在，先销毁它
      }
      // 创建一个新的图表实例
      var myChart = echarts.init(document.getElementById(id));

      var option = {
        title: {
          // text: title,
          top: 10,
          padding: [-5, 0],
          textStyle: {
            fontSize: 20
          },
          subtextStyle: {
            fontSize: 12
          },
          triggerEvent: true
        },
        legend: [{ data: ['电池电量'] }],
        toolbox: this.toolbox,
        animation: false,
        tooltip: this.tooltip,
        grid: {
          left: '5%',
          right: '14%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          data: [
            '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'
          ],
          name: '时间\n(s)',
          nameLocation: 'end', // 将横坐标名称放在轴线末端
          nameTextStyle: {
            fontSize: 14,
            fontWeight: 'bold',
            padding: [10, 0, 0, 0] // 调整横坐标名称与轴线的距离
          },
          axisTick: {
            alignWithLabel: true
          },
          axisLine: {
            symbol: ['none', 'arrow'],
            symbolSize: [8, 16],
            lineStyle: {
              color: '#333',
              width: 2
            }
          }
        },
        yAxis: {
          axisLabel: {
            formatter: function (value) {
              return value.toFixed(2)
            }
          },
          name: '电池电量\n(%)',
          nameLocation: 'end', // 将纵坐标名称放在轴线末端
          nameTextStyle: {
            fontSize: 14,
            fontWeight: 'bold',
            padding: [0, 10, 0, 0] // 调整纵坐标名称与轴线的距离
          },
          axisTick: {
            alignWithLabel: true
          },
          scale: true,
          axisLine: {
            show: true,
            symbol: ['none', 'arrow'],
            symbolSize: [5, 15],
            symbolOffset: [0, 15],
            lineStyle: {
              type: 'dashed'
            }
          }
        },
        series: [
          {
            name: '电池电量',
            symbol: 'circle',
            type: 'line',
            stack: 'Total1',
            itemStyle: {
              borderWidth: 0
            },
            data: realdata
          }
        ]
      }

      myChart.setOption(option)
    },
    drawLine2(id, title, realdata) {
      var chart = echarts.getInstanceByDom(document.getElementById(id));
      if (chart) {
        chart.dispose(); // 如果图表已经存在，先销毁它
      }

      this.gaugeData[0].value = realdata;
      // 创建一个新的图表实例
      var myChart = echarts.init(document.getElementById(id));


      var option = {
        series: [
          {
            type: 'gauge',
            startAngle: 90,
            endAngle: -270,
            pointer: {
              show: false
            },

            tooltip: {},
            progress: {
              show: true,
              overlap: false,
              roundCap: true,
              clip: false,
              itemStyle: {
                borderWidth: 1,
                borderColor: '#464646'
              }
            },
            axisLine: {
              lineStyle: {
                width: 10
              }
            },
            splitLine: {
              show: false,
              distance: 20,
              length: 10
            },
            axisTick: {
              show: false
            },
            axisLabel: {
              show: false,
              distance: 50
            },
            data: this.gaugeData,
            title: {
              fontSize: 30
            },
            detail: {
              width: 120,
              height: 40,
              fontSize: 35,
              color: 'inherit',
              borderColor: 'inherit',
              borderRadius: 30,
              borderWidth: 1,
              formatter: '{value}%'
            }
          }
        ]
      };

      myChart.setOption(option)
    },
    clickOne() {
      this.intervalId1 = setInterval(() => {
        axios.get('http://127.0.0.1:8000/data').then((res) => {
          console.log('res', res.data)
          this.clickValue4 = true;
          console.log('clickValue4', this.clickValue4)
          // const tem = res.data.data[0].Value.toFixed(2); //温度
          const electicy = parseFloat(res.data.data[3].Value).toFixed(2);
          // const hug = res.data.data[2].Value //烟雾
          // const ele = res.data.data[3].Value //电池
          // 将数据添加到数组中

          if (electicy < 20) {
            this.eleWarning = true;
          }

          arr4.push(electicy)
          // arr4.push(hug)
          // arr4.push(ele)

          // 如果数组的长度超过了 10，就将数组的第一个元素删除
          if (arr4.length > 10) {
            arr4.shift()
          }

          // 异常数据收集
          const lastValue = arr4[arr4.length - 1]
          if (lastValue < 20) {
            const currentTime = new Date().toLocaleString()
            console.log('thistableData4', this.tableData4)
            this.tableData4.push({ value: lastValue, time: currentTime })
            console.log('newthistableData4', this.tableData4)
          }
          // if (arr4.length > 10) {
          //   arr4.shift()
          // }
          // if (arr4.length > 10) {
          //   arr4.shift()
          // }
          this.arrFour = arr4.map((item) => Number(item));;
          console.log('点击后arrFour', this.arrFour)
          console.log('温度', arr4)
          // console.log('烟雾', arr4)
          // console.log('电池', arr4)

          this.drawLine('chart11', '温度', arr4);
          this.realData = arr4[9];
          this.updateChartData('chart12');
          // this.drawLine2('chart12', '温度', arr4[9]);
          this.eleData = this.arrFour[9];
          console.log('eleData', this.eleData);
          this.ele = arr4[9].toString() + '%';
          console.log('ele', this.ele)
        });

      }, 1000)
    },
    clickTwo() {
      this.intervalId2 = setInterval(() => {
        // this.drawLine('chart11', '温度', arr4);
        // this.drawLine2('chart12', '温度', arr4[9]);
        // this.eleData = this.arrFour[9];
        // console.log('eleData', this.eleData);
        // this.ele = arr4[9].toString();
        // console.log('ele',this.ele)
      }, 1000)
    },
    stopClickOne() {
      this.clickValue4 = false;
      clearInterval(this.intervalId1);
    },
    stopClickTwo() {
      clearInterval(this.intervalId2);
    },
    pre1() {
      this.preIf = true;
      const n = 10;
      if (n < 2) {
        return null;
      }
      let sum = 0;
      for (let i = n - 1; i >= n - 5; i--) {
        sum += parseFloat(this.arrFour[i]);
      }
      this.preValue1 = (sum / 5).toFixed(2);
      console.log('preValue1', this.preValue1);
    },
    pre2() {
      this.preIf = true;
      function DecisionTreeNode() {
        this.value = null;
        this.children = {};
      }

      function buildDecisionTree(features, labels) {
        const root = new DecisionTreeNode();
        if (labels.length === 0) {
          return root;
        }
        const uniqueLabels = [...new Set(labels)];
        if (uniqueLabels.length === 1) {
          root.value = uniqueLabels[0];
          return root;
        }
        const bestFeatureIndex = findBestFeature(features, labels);
        const bestFeatureName = `feature${bestFeatureIndex + 1}`;
        root.value = bestFeatureName;
        const uniqueFeatures = [...new Set(features.map((feature) => feature[bestFeatureIndex]))];
        for (const featureValue of uniqueFeatures) {
          const childFeatures = features.filter((feature) => feature[bestFeatureIndex] === featureValue);
          const childLabels = labels.filter((label, index) => features[index][bestFeatureIndex] === featureValue);
          root.children[featureValue] = buildDecisionTree(childFeatures, childLabels);
        }
        return root;
      }

      function predictDecisionTree(data, decisionTree) {
        let node = decisionTree;
        while (node.value !== null) {
          const featureIndex = parseInt(node.value.slice(7)) - 1;
          const featureValue = data[featureIndex];
          if (!(featureValue in node.children)) {
            return null;
          }
          node = node.children[featureValue];
        }
        return node.value;
      }

      function findBestFeature(features, labels) {
        const numFeatures = features[0].length;
        let bestFeatureIndex = -1;
        let bestInfoGain = -Infinity;
        const entropy = getEntropy(labels);
        for (let i = 0; i < numFeatures; i++) {
          const featureValues = features.map((feature) => feature[i]);
          const uniqueFeatureValues = [...new Set(featureValues)];
          let featureEntropy = 0;
          for (const featureValue of uniqueFeatureValues) {
            const featureLabels = labels.filter((label, index) => featureValues[index] === featureValue);
            const featureProb = featureLabels.length / labels.length;
            featureEntropy += featureProb * getEntropy(featureLabels);
          }
          const infoGain = entropy - featureEntropy;
          if (infoGain > bestInfoGain) {
            bestFeatureIndex = i;
            bestInfoGain = infoGain;
          }
        }
        return bestFeatureIndex;
      }

      function getEntropy(labels) {
        const numLabels = labels.length;
        const labelCounts = {};
        for (const label of labels) {
          if (!(label in labelCounts)) {
            labelCounts[label] = 0;
          }
          labelCounts[label]++;
        }
        let entropy = 0;
        for (const label in labelCounts) {
          const prob = labelCounts[label] / numLabels;
          entropy -= prob * Math.log2(prob);
        }
        return entropy;
      }

      const arrFourpre2 = this.arrFour.map((item) => {
        return !isNaN(item) ? parseInt(item) : item;
      });
      console.log('arrFourpre2', arrFourpre2)

      const windowSize = 10;
      const numLabels = 1; // 预测一个值
      const features = [];
      const labels = [];

      // 构建特征和标签
      for (let i = 0; i < arrFourpre2.length - windowSize - numLabels + 1; i++) {
        const feature = arrFourpre2.slice(i, i + windowSize);
        const label = arrFourpre2[i + windowSize + numLabels - 1];
        features.push(feature);
        labels.push(label);
      }

      // 创建决策树模型
      const decisionTree = buildDecisionTree(features, labels);

      // 预测数据
      const testData = arrFourpre2.slice(-windowSize);
      const prediction = predictDecisionTree(testData, decisionTree);
      console.log(prediction); // 输出预测结果
      // console.log('preValue2',this.preValue2)
    },
    pre3() {
      this.preIf = true;

      const arrFourpre3 = this.arrFour.map((item) => {
        return !isNaN(item) ? parseInt(item) : item;
      });
      console.log('arrFourpre3', arrFourpre3)

      const alpha = 0.5;
      const beta = 0.3;

      const n = arrFourpre3.length;
      // 初始化level和trend
      let level = [arrFourpre3.slice(0, 2).reduce((a, b) => a + b) / 2];
      let trend = [(arrFourpre3[1] - arrFourpre3[0]) / 2];
      // 预测值列表
      const predictedData = [level[0] + trend[0]];
      for (let i = 1; i < n; i++) {
        // 计算level和trend
        level.push(alpha * arrFourpre3[i] + (1 - alpha) * (level[i - 1] + trend[i - 1]));
        trend.push(beta * (level[i] - level[i - 1]) + (1 - beta) * trend[i - 1]);
        // 计算预测值
        predictedData.push(level[i] + trend[i]);
      }
      this.preValue3 = predictedData;
      this.preValue3 = this.preValue3.map(item => parseFloat(item.toFixed(2)));


      // // 计算level和trend
      // level.push(alpha * arrFourpre3[n-1] + (1 - alpha) * (level[n-1 - 1] + trend[n-1 - 1]));
      // trend.push(beta * (level[n-1] - level[n-1 - 1]) + (1 - beta) * trend[n-1 - 1]);
      // // 计算预测值
      // predictedData.push(level[n-1] + trend[n-1]);

      // this.preValue3 = predictedData;
      console.log('this.preValue3', this.preValue3)
    },
    openeleWarning() {
      ElNotification({
        title: '节点一Error',
        message: '电量预警',
        type: 'error',
        duration: 0,
      })
    },
    // 表格导出
    exportExcel(tabid, name) {
      const wb = XLSX.utils.table_to_book(document.querySelector('#' + tabid), {
        raw: true // 如果表格里有数字、日期这些、需要加上raw: true
      });
      /* 获取二进制字符串作为输出 */
      var wbout = XLSX.write(wb, {
        bookType: 'xlsx',
        bookSST: true,
        type: 'array'
      });
      try {
        FileSaver.saveAs(
          // Blob 对象表示一个不可变、原始数据的类文件对象。
          new Blob([wbout], { type: 'application/octet-stream' }),
          // 设置导出文件名称
          name
        );
      } catch (e) {
        if (typeof console !== 'undefined') console.log(e, wbout);
      }
      return wbout;
    }
  },
  mounted() {
    this.arrFour = arr4;
    console.log('arrFour', this.arrFour)
    this.eleData = this.arrFour[9]
    console.log('eleData', this.eleData);
    this.drawLine('chart11', '电池电量', arr4);
    this.drawLine2('chart12', '电池电量', arr4[9]);
  },
  computed: {
  },
  watch: {
    arrFour: {
      handler: function (newVal, oldVal) {
        console.log('123');
        if (this.clickValue4) {
          console.log('数组arrFour发生变化', newVal, oldVal);
          this.clickTwo();
        }
      },
      deep: true
    },
    eleWarning(newVal) {
      if (newVal) {
        this.openeleWarning();
        this.eleWarning = false;
      }
    },
  },
  beforeUnmount() {
    this.stopClickOne();
    this.stopClickTwo();
  },


};
</script>

